﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Xml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SimpleExpression;
using SQLExpressionBuilder;
using SQLExpressionBuilder.Commands;

namespace SQLExpressionBuilderTest
{
    [TestClass]
    public class UnitTest1
    {
		[TestMethod]
		public void TestMethod1()
		{
            GenericTest();   
		}

        public void LambdaExpressionTest()
        {
            LinqExpressionVisitor visitor = new LinqExpressionVisitor(EntityMetadata.GetEntity("Customer"));

            Guid id = Guid.Empty;

            System.Linq.Expressions.Expression<Func<Customer, bool>> expression = (c) => c.CustomerId == id && c.FirstName == "Greivin";
            
            object obj = visitor.Visit(expression);
        }
        
        public void GenericTest()
        {
            EntityExpression expression = new EntityExpression("Customer");

            expression.Select((Customer c) => new { c.FirstName, c.LastName, c.Age });
            expression.Where((Customer c) => c.FirstName == "Greivin");
            expression.Order((Customer c) => new { c.Age, c.FirstName });

            SqlSelectPlan selectPlan = new SqlSelectPlan(expression);
            Debug.Write(((SqlCommand)selectPlan.Command).CommandText);

            /*EntityExpression<Customer> expression2 = new EntityExpression<Customer>(EntityMetadata.GetEntity("Customer"));

            expression2.Select(c => new { c.FirstName, c.LastName });
            expression2.Where(c => c.FirstName == "Greivin");
            expression2.Group(c => c.FirstName);
            expression2.Order(c => new { c.Age, c.FirstName });

            selectPlan = new SqlSelectPlan(expression2);
            Debug.Write(((SqlCommand)selectPlan.Command).CommandText);
            */
        }

		public void TestDeserialization()
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(@"E:\testEntityExpression.xml");

			EntityExpression expression;
			ExpressionSelectCommandXmlStrategy converter = new ExpressionSelectCommandXmlStrategy(doc);
			expression = converter.processXml();

			SelectPlan selectPlan = new SelectPlan(expression, new XMLSelectCommandStrategy());

			Debug.WriteLine(Environment.NewLine);
			Debug.Write(selectPlan.Command);
			Debug.WriteLine(Environment.NewLine); 

		}

        private void Test3()
        {
            EntityExpression expression = new EntityExpression("Entity");
            
            //Create
            CreateCommand createExpression = new CreateCommand();
            createExpression.ToCommand();

            //Read
            SelectPlan selectPlan = new SelectPlan(expression, new XMLSelectCommandStrategy());
            Debug.WriteLine(Environment.NewLine);
            Debug.Write(selectPlan.Command);
            Debug.WriteLine(Environment.NewLine);

            //Delete
            DeleteCommand deleteExpression = new DeleteCommand();
            deleteExpression.ToCommand();

            //Update
            UpdateCommand updateExpression = new UpdateCommand();
            updateExpression.ToCommand();
        }

        private void Test2()
        { 
            EntityExpression expression = new EntityExpression("Entity");
            expression.ColumnSetExpression.AddAllColumns();

            expression.FilterExpression.Add("Campo1", ConditionOperator.Equals, "1");
            expression.FilterExpression.Add("Campo2", ConditionOperator.Equals, "dfadsf");
			
			expression.GroupByExpression.Add(expression.EntityMetadata["Campo3"]);


            //FilterExpression filterExpression = new FilterExpression(expression.EntityMetadata);
			FilterExpression filterExpression = new FilterExpression(LogicalOperator.Or);
			filterExpression.EntityMetadata = expression.EntityMetadata;

            filterExpression.Add("Campo3", ConditionOperator.Equals, "3", LogicalOperator.Or);
            filterExpression.Add("Campo4", ConditionOperator.Equals, "3");
			
			//filterExpression.LogicalOperator = LogicalOperator.Or;

            expression.FilterExpression.Add(filterExpression);

            expression.PagingExpression.Start = 10;
            expression.PagingExpression.Limit = 20;

            expression.OrderExpression.Add(expression.EntityMetadata["Campo3"], OrderType.ASC);

            LinkEntityExpression linkEntity = expression.JoinEntityExpression.Add("Tabla1", JoinOperator.INNER, "Campo1", "Campo1");
            linkEntity.FilterExpression.Add(linkEntity.EntityTo["Campo3"], ConditionOperator.Equals, expression.EntityMetadata["Campo3"]);
            linkEntity.FilterExpression.Add(linkEntity.EntityTo["Campo4"], ConditionOperator.Different, 3);


			LinkEntityExpression linkEntity2 =  expression.JoinEntityExpression.Add("Tabla3", JoinOperator.LEFT, "Campo1", "Campo2");
			linkEntity2.FilterExpression.Add(linkEntity.EntityTo["Campo3"], ConditionOperator.Equals, expression.EntityMetadata["Campo3"]);
			linkEntity2.FilterExpression.Add(linkEntity.EntityTo["Campo4"], ConditionOperator.Different, 3);

            /*XmlSerializer serializer = new XmlSerializer(typeof(EntityExpression));
            TextWriter textWriter = new StreamWriter(@"c:\entityexpression.xml");
            serializer.Serialize(textWriter, expression);
            textWriter.Close();
			*/
            //Read
            SqlSelectPlan selectPlan = new SqlSelectPlan(expression);

            Debug.WriteLine(Environment.NewLine);
            Debug.Write(((SqlCommand)selectPlan.Command).CommandText);
            Debug.WriteLine(Environment.NewLine);
        }

        private void Test1()
        {
            /* Codigo de prueba con todas las opciones
                 * Comentariado por propositos de prueba
                 * EntityExpression expression = new EntityExpression("Entity");
                expression.ColumnSetExpression.AddAllColumns();
                expression.GroupByExpression.Add("Campo1");

                LinkEntityExpression join1 = expression.JoinEntityExpression.Add("Tabla2", JoinOperator.INNER, "Campo1", "Campo1");
                join1.FilterExpression.Add("Campo2", ConditionOperator.Different, join1.EntityTo["Campo2"]);
            
                //expression.LinkEntityExpression.Add("Tabla3", JoinOperator.INNER, "Campo1", "Campo2");

                expression.PagingExpression = new PagingExpression() { Start = 0, Limit = 10 };
                expression.FilterExpression.Add("Campo1", ConditionOperator.Equals, "1");
                expression.FilterExpression.Add("Campo2", ConditionOperator.Equals, "2", LogicalOperator.Or);
                expression.FilterExpression.Add("Campo3", ConditionOperator.Equals, "3");
                expression.FilterExpression.Add("Campo4", ConditionOperator.Equals, "4", LogicalOperator.Or);
            
                FilterExpression filterExpression = new FilterExpression(expression.EntityMetadata);
                filterExpression.Add("Campo5", ConditionOperator.Equals, "5");
                filterExpression.Add("Campo6", ConditionOperator.Equals, "6", LogicalOperator.Or);

                FilterExpression filterExpression2 = new FilterExpression(expression.EntityMetadata);
                filterExpression2.Add("Campo7", ConditionOperator.Equals, "7");
                filterExpression2.Add("Campo8", ConditionOperator.Equals, "8", LogicalOperator.Or);
                filterExpression.Add(filterExpression2);

                expression.FilterExpression.Add(filterExpression);

                EntityMetadata entity4 = EntityMetadata.GetEntity("Tabla4");

                expression.JoinEntityExpression.Add("Tabla3", JoinOperator.LEFT, "Campo3", "Campo3");

                expression.JoinEntityExpression.Add(JoinOperator.LEFT, join1.FieldTo, entity4["Campo4"]);
                */

            //Read
            //SelectPlan selectPlan = new SelectPlan(expression, new XMLSelectCommandStrategy());
            //Debug.WriteLine(Environment.NewLine);
            //Debug.Write(selectPlan.Command);
            //Debug.WriteLine(Environment.NewLine);

        }

        private static void WriteCommand(IDbCommand command)
        {
            Debug.WriteLine(Environment.NewLine);
            Debug.Write(command.CommandText);
            Debug.WriteLine(Environment.NewLine);
        }
    }
}
